﻿#include "dxstdafx.h"
#include "TerrainTypeInfoIO.h"

// (_stTerrainTypeInfo*)(m_list_OperatorPtr.back())->P = (*T)(vp)  普通赋值操作
#define NORMAL_ASSIGN(P, T)\
[this](const void* vp){ CHECK_RETURN(vp);\
		_stTerrainTypeInfo* cp = static_cast<_stTerrainTypeInfo*>(m_list_OperatorPtr.back());\
		CHECK_RETURN(cp);\
		const T* tp = static_cast<const T*>(vp);\
		CHECK_RETURN(tp);\
		cp->P =  *tp; }\

CTerrainTypeInfoReaderHandle::CTerrainTypeInfoReaderHandle(std::unordered_map<std::wstring, _stTerrainTypeInfo>* map)
	: BaseReaderHandler(map)
{
	m_map_OperatorFunction = {
		{ L"is_water", NORMAL_ASSIGN(bIsWater, bool) },
		{ L"inland_sea", NORMAL_ASSIGN(bInlandSea, bool) },
		{ L"supply_limit", NORMAL_ASSIGN(nSupplyLimit, int) },
		{ L"bottleneck_chance", NORMAL_ASSIGN(nBottleneckChance, int) },
		{ L"movement_cost", NORMAL_ASSIGN(fMovementCost, double) },
		{ L"defence", NORMAL_ASSIGN(fDefence, double) },
		{ L"max_attrition", NORMAL_ASSIGN(fMaxAttrition, double) },
		{ L"name_index", NORMAL_ASSIGN(DisplayNameIndex, std::wstring) },
	};
}

bool CTerrainTypeInfoReaderHandle::HandleBool(const std::wstring& key, bool b)
{
	return OperatorFunction(key, &b);
}

bool CTerrainTypeInfoReaderHandle::HandleInt(const std::wstring& key, int i)
{
	return OperatorFunction(key, &i);
}

bool CTerrainTypeInfoReaderHandle::HandleDouble(const std::wstring& key, double d)
{
	return OperatorFunction(key, &d);
}

bool CTerrainTypeInfoReaderHandle::HandleString(const std::wstring& key, const std::wstring& str)
{
	return OperatorFunction(key, &str);
}

bool CTerrainTypeInfoReaderHandle::HandleStartObj(const std::wstring& key)
{
	if (!key.empty())
	{
		CHECK_RE_FALSE(m_Container);
		_stTerrainTypeInfo stTerrainTypeInfo;
		stTerrainTypeInfo.KeyName = key;
		auto iterInsert = m_Container->insert(std::make_pair(key, stTerrainTypeInfo));
		if (!iterInsert.second)
		{
			CString strError;
			strError.Format(L"'%s' is repeat!", key);
			CommonFunc::ErrorMessageBox(strError);
			return false;
		}
		else
		{
			m_list_OperatorPtr.push_back(&iterInsert.first->second);
		}
	}
	
	return true;
}

bool CTerrainTypeInfoReaderHandle::HandleEndObj()
{
	if (!m_list_OperatorPtr.empty())
	{
		m_list_OperatorPtr.pop_back();
	}
	return true;
}